#ifndef MONO_PARSER_PROPERTY_NODE_H_
#define MONO_PARSER_PROPERTY_NODE_H_
#include <string>
#include <vector>
#include <map>
#include <memory>
#include <cstddef>

namespace mono {

typedef std::pair<std::string, std::string> Property;

class PropertyNode;
typedef std::shared_ptr<PropertyNode> PropertyNodePtr;

class PropertyNode {
public:
	explicit PropertyNode(const std::string & name);
	
	void addAttribute(const std::string & attribute);
	void addProperty(const Property & property);
	void addNode(const PropertyNodePtr & node);
	
	size_t getNumProperties() const;
	size_t getNumAttributes() const;
	size_t getNumNodes() const;
	
	bool getAttribute(size_t id, std::string &value) const;
	bool getProperty(const std::string & name, const std::string & defaultValue, std::string& value) const;
	bool getProperty(const std::string & name, std::string &value) const;
	bool getProperty(size_t id, Property&value) const;

	std::string getName() const;
	
	const PropertyNodePtr getNode(size_t id) const;
	const PropertyNodePtr getNode(const std::string & name) const;
	PropertyNodePtr getNode(const std::string & name);

public:
	static const std::string KNotExists;
	static const std::string KOutOfRange;	
	static PropertyNodePtr MergeTrees(const PropertyNodePtr & base, const PropertyNodePtr & sub);
	
private:
	typedef std::map<std::string, std::string> PropertyMap;
	
	PropertyMap                   _properties;
	std::vector<PropertyNodePtr>  _children;
	std::vector<std::string>      _attributes;
	std::string                   _name;
};

}
#endif //MONO_PARSER_PROPERTY_NODE_H_
